<template>
	<div id="flowDiv"></div>
</template>
<script>
	import go from 'gojs'
	import { getAction } from '@/utils/httpUtil'
	import flowApi from '@/api/workFlowApi'
	let gmake = go.GraphObject.make
	export default {
		name: 'FlowInfo',
		props: {
			formId: {
				default: '',
			},
			finish: {
				type: Boolean,
				default: false,
			},
		},
		data() {
			return {
				myDiagram: null,
				lightText: 'whitesmoke',
				od: true,
				actvieNode: null, //gojs 中 当前  可用的节点
				activeName: 'first',
				node: [],
				edge: [],
				bkcolor: ['#5cadff', '#19be6b', '#5E77FF'],
				lkcolor: ['#666'],
			}
		},
		watch: {
			formId: {
				immediate: true,
				handler: function(newValue, oldValue) {
					if (newValue) {
						this.loadWorkFLowInfo()
					}
				},
			},
		},
		mounted() {
			this.initFlowComponent()
		},
		methods: {
			initFlowComponent() {
				this.myDiagram = gmake(
					go.Diagram,
					'flowDiv', // 网格锁定must name or refer to the DIV HTML element
					{
						initialContentAlignment: go.Spot.Center,
						allowDrop: true, // must be true to accept drops from the Palette
						scrollsPageOnFocus: false,
						'undoManager.isEnabled': true, // enable undo & redo
						allowRelink: true,
						padding: 0,
						isReadOnly: true,
						'draggingTool.isGridSnapEnabled': true, //自动锁定
						nodeSelectionAdornmentTemplate: gmake(
							go.Adornment,
							'Auto',
							gmake(go.Shape, 'Rectangle', {
								fill: 'white',
								stroke: null,
							})
						),
						doubleClick: function(e) {
							console.log(e)
						},
					}
				)
				this.myDiagram.nodeTemplateMap.add(
					'all', //流程
					gmake(
						go.Node,
						'Spot',
						this.nodeStyle(),
						{
							resizable: true,
							resizeObjectName: 'PANEL',
							doubleClick: function(e, node) {
								console.log(this.node)
								if (node.data.enable) {
									let flge = this.node.find(item => item.state == 0)
									if (flge && flge.repId) {
										this.wpId = flge.repId
									}
									this.showCell = true
								}
							},
							//	            isShadowed: true,//加阴影
						},
						gmake(
							go.Panel,
							'Auto',
							gmake(
								go.Shape,
								'RoundedRectangle',
								{
									fill: 'rgba(83, 168, 255, 1)',
									stroke: '#09d3ac',
									strokeWidth: 0,
									name: 'nodeshape',
									minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
								},
								new go.Binding('fill', 'bkcolor').makeTwoWay()
							),
							gmake(
								go.TextBlock,
								{
									font: 'bold 12px Helvetica, Arial, sans-serif',
									stroke: this.lightText, //stroke  字体
									wrap: go.TextBlock.WrapFit,
									textAlign: 'center',
									editable: false,
									name: 'nodetext',
								},
								new go.Binding('text').makeTwoWay(),

								new go.Binding('nodestate').makeTwoWay()
							)
						),
						new go.Binding('width').makeTwoWay(),
						new go.Binding('height').makeTwoWay(),
						// three named ports, one on each side except the top, all output only:
						this.makePort('T', go.Spot.Top, true, true),
						this.makePort('L', go.Spot.Left, true, true),
						this.makePort('R', go.Spot.Right, true, true),
						this.makePort('B', go.Spot.Bottom, true, true)
					)
				)

				this.myDiagram.nodeTemplateMap.add(
					'Start', //开始
					gmake(
						go.Node,
						'Spot',
						this.nodeStyle(),
						{
							resizable: true,
							resizeObjectName: 'PANEL',
							doubleClick: function(e, node) {
								if (node.data.enable) {
									this.showCell = true
								}
							},
							//	            isShadowed: true,//加阴影
						},
						gmake(
							go.Panel,
							'Auto',
							gmake(
								go.Shape,
								'Ellipse',
								{
									//	                minSize: new go.Size(35, 35),
									fill: 'rgba(83, 168, 255, 1)',
									stroke: '#00A9C9',
									strokeWidth: 0,
									name: 'nodeshape',
									minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
								},
								new go.Binding('fill', 'bkcolor').makeTwoWay(),
								new go.Binding('figure', 'figure')
							),
							gmake(
								go.TextBlock,
								'Start',
								{
									font: 'bold 12px Helvetica, Arial, sans-serif',
									stroke: this.lightText,
									textAlign: 'center',
									name: 'nodetext',
								},
								new go.Binding('text').makeTwoWay(),
								new go.Binding('nodestate').makeTwoWay()
							)
						),
						new go.Binding('width').makeTwoWay(),
						new go.Binding('height').makeTwoWay(),
						this.makePort('T', go.Spot.Top, true, false),
						this.makePort('L', go.Spot.Left, true, false),
						this.makePort('R', go.Spot.Right, true, false),
						this.makePort('B', go.Spot.Bottom, true, false)
					)
				)

				this.myDiagram.nodeTemplateMap.add(
					'End',
					gmake(
						go.Node,
						'Spot',
						this.nodeStyle(),
						{
							resizable: true,
							resizeObjectName: 'PANEL',
							//	            isShadowed: true,//加阴影
							doubleClick: function(e, node) {
								console.log(node)
							},
						},
						gmake(
							go.Panel,
							'Auto',
							gmake(
								go.Shape,
								'Ellipse',
								{
									//	              minSize: new go.Size(35, 35),
									fill: 'rgba(83, 168, 255, 1)',
									stroke: '#009688',
									strokeWidth: 0,
									name: 'nodeshape',
									minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
								},
								new go.Binding('fill', 'bkcolor').makeTwoWay()
							),
							gmake(
								go.TextBlock,
								'End',
								{
									font: 'bold 12px Helvetica, Arial, sans-serif',
									stroke: this.lightText,
									textAlign: 'center',
									name: 'nodetext',
								},
								new go.Binding('text').makeTwoWay(),
								new go.Binding('nodestate').makeTwoWay()
							)
						),
						new go.Binding('width').makeTwoWay(),
						new go.Binding('height').makeTwoWay(),
						this.makePort('T', go.Spot.Top, false, true),
						this.makePort('L', go.Spot.Left, false, true),
						this.makePort('R', go.Spot.Right, false, true),
						this.makePort('B', go.Spot.Bottom, false, true)
					)
				)
				//	      this.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
				//	      this.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal; //线的转弯
				this.myDiagram.nodeTemplateMap.add(
					'textblo',
					gmake(
						go.Node,
						'Auto',
						this.nodeStyle(),
						{
							resizable: true,
							resizeObjectName: 'PANEL',
							text: 'node',
							doubleClick: function(e, node) {
								console.log(node)
							},
							//	            isShadowed: true,//加阴影
						},
						gmake(
							go.Panel,
							'Auto',
							gmake(
								go.Shape,
								{
									fill: 'rgba(83, 168, 255, 1)',
									stroke: '#607d8b',
									strokeWidth: 0,
									name: 'nodeshape',
									minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
								},
								new go.Binding('fill', 'bkcolor').makeTwoWay(),
								new go.Binding('text').makeTwoWay()
							),
							gmake(
								go.TextBlock,
								{
									margin: 5,
									wrap: 30,
									textAlign: 'center',
									editable: true,
									font: 'Arial',
									stroke: '#ffffff',
									name: 'nodetext',
								},
								new go.Binding('text').makeTwoWay(),
								new go.Binding('nodestate').makeTwoWay()
							),
							new go.Binding('text').makeTwoWay()
						)
					)
				)

				this.myDiagram.nodeTemplateMap.add(
					'Comment',
					gmake(
						go.Node,
						'Spot',
						this.nodeStyle(),
						{
							resizable: true,
							resizeObjectName: 'PANEL',
							click: function(e, node) {
								console.log(node)
							},
							doubleClick: function(e, node) {
								console.log(node)
							},
							//	            isShadowed: true,//加阴影
						},
						gmake(
							go.Panel,
							'Auto',
							gmake(
								go.Shape,
								'Diamond',
								{
									//	              minSize: new go.Size(60, 30),
									fill: 'rgba(83, 168, 255, 1)',
									stroke: null,
									strokeWidth: 0,
									name: 'nodeshape',
									minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
								},
								new go.Binding('fill', 'bkcolor').makeTwoWay()
							),
							gmake(
								go.TextBlock,
								'???',
								{
									wrap: go.TextBlock.WrapFit,
									textAlign: 'center',
									font: 'bold 12px Helvetica, Arial, sans-serif',
									stroke: '#fff',
									name: 'nodetext',
								},
								new go.Binding('text').makeTwoWay(),
								new go.Binding('nodestate').makeTwoWay()
							)
						),
						new go.Binding('width').makeTwoWay(),
						new go.Binding('height').makeTwoWay(),
						this.makePort('T', go.Spot.Top, true, true),
						this.makePort('L', go.Spot.Left, true, true),
						this.makePort('R', go.Spot.Right, true, true),
						this.makePort('B', go.Spot.Bottom, true, true)
					)
				)

				this.myDiagram.linkTemplate = gmake(
					go.Link, // the whole link panel
					{
						routing: go.Link.AvoidsNodes,
						selectionAdorned: true,
						mouseEnter: function(e, link) {
							link.findObject('HIGHLIGHT').stroke = 'rgba(30,144,255,0.2)'
						},
						mouseLeave: function(e, link) {
							link.findObject('HIGHLIGHT').stroke = 'transparent'
						},
						doubleClick: function(e, link) {
							console.log(link)
						},
					},
					new go.Binding('points').makeTwoWay(),
					gmake(
						go.Shape, // the highlight shape, normally transparent
						{
							isPanelMain: true,
							strokeWidth: 8,
							stroke: 'transparent',
							name: 'HIGHLIGHT',
						}
					),
					gmake(
						go.Shape, // the link path shape
						{
							isPanelMain: true,
							stroke: 'gray',
							strokeWidth: 2,
						},
						new go.Binding('stroke', 'lkcolor').makeTwoWay(),
						new go.Binding('fill', 'lkcolor').makeTwoWay()
					),
					gmake(
						go.Shape, // the arrowhead
						{
							toArrow: 'standard',
							stroke: 'gray',
							fill: 'gray',
						},
						new go.Binding('stroke', 'lkcolor').makeTwoWay(),
						new go.Binding('fill', 'lkcolor').makeTwoWay()
					),
					gmake(
						go.Panel,
						'Auto', // the link label, normally not visible
						{
							visible: true,
						},
						new go.Binding('visible', 'visible').makeTwoWay(),
						gmake(
							go.Shape,
							'RoundedRectangle', // the label shape
							{
								fill: 'transparent',
								stroke: null,
							}
						),
						gmake(
							go.TextBlock,
							' ', // the label
							{
								textAlign: 'center',
								font: '10pt helvetica, arial, sans-serif',
								stroke: '#999',
								editable: false,
							},
							new go.Binding('text').makeTwoWay(),
							new go.Binding('name').makeTwoWay()
						)
					)
				) //线上文字
			},
			nodeStyle(e, obj) {
				let _this = this
				return [
					new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
					{
						locationSpot: go.Spot.Center,
						mouseEnter: function(e, obj) {
							_this.showPorts(obj.part, true)
						},
						mouseLeave: function(e, obj) {
							_this.showPorts(obj.part, false)
						},
					},
				]
			},
			showPorts(node, show) {
				let diagram = node.diagram
				if (!diagram || diagram.isReadOnly || !diagram.allowLink) return
				node.ports.each(function(port) {
					port.stroke = show ? 'white' : null
				})
			},
			//当鼠标选中的时候出现可以连线的点，一般有上下左右四个点
			makePort(name, spot, output, input) {
				//不能用demo4的  makePort  要不然边框会缺失
				// the port is basically just a small circle that has a white stroke when it is made visible
				return go.GraphObject.make(go.Shape, 'Circle', {
					fill: 'transparent',
					stroke: null, // this is changed to "white" in the showPorts function
					desiredSize: new go.Size(8, 8),
					name: name + 'circle',
					alignment: spot,
					alignmentFocus: spot, // align the port on the main Shape
					portId: name, // declare this object to be a "port"
					fromSpot: spot,
					toSpot: spot, // declare where links may connect at this port
					fromLinkable: output,
					toLinkable: input, // declare whether the user may draw links to/from here
					cursor: 'pointer', // show a different cursor to indicate potential link point
				})
			},
			setNode(tnode) {
				this.node.forEach((node, index) => {
					if (node.wfNodeCode == tnode.key) {
						this.myDiagram.model.setDataProperty(tnode, 'bkcolor', this.bkcolor[node.state])
						if (node.state == 0) {
							//设置节点状态
							this.myDiagram.model.setDataProperty(tnode, 'enable', true)
							this.actvieNode = tnode
							this.timer = setInterval(this.setActiveNode, 800)
						}
					}
				})
			},
			setLink(tedge) {
				this.edge.forEach((edge, index) => {
					if (edge.wfEdgeCode == tedge.key) {
						this.myDiagram.model.setDataProperty(tedge, 'lkcolor', this.lkcolor[0])
					}
				})
			},
			initNode() {
				//遍历
				this.myDiagram.model.nodeDataArray.forEach((node, index) => {
					this.myDiagram.model.setDataProperty(node, 'enable', false)
					this.myDiagram.model.setDataProperty(node, 'bkcolor', '#c5c8ce')
					this.setNode(node)
				})
				this.myDiagram.model.linkDataArray.forEach((link, index) => {
					this.myDiagram.model.setDataProperty(link, 'lkcolor', '#c5c8ce')
					this.setLink(link)
				})
			},
			loadWorkFLowInfo() {
				getAction(flowApi.flowImg, { assetManageId: this.formId, finish: this.finish }).then(res => {
					if (res.success) {
						this.myDiagram.model = go.Model.fromJson(res.info.pic)
						this.node = res.info.node
						this.edge = res.info.edge
						this.initNode()
					}
				})
			},
			setActiveNode() {
				//设置闪动节点
				if (this.actvieNode) {
					if (this.od) {
						this.myDiagram.model.setDataProperty(this.actvieNode, 'bkcolor', 'rgba(92, 173, 255,0.85)')
					} else {
						this.myDiagram.model.setDataProperty(this.actvieNode, 'bkcolor', '#5cadff')
					}
					this.od = !this.od
				}
			},
		},
	}
</script>

<style lang="scss" scoped>
	#flowDiv {
		flex-grow: 1;
		background-color: var(--page-back-color);
		// min-height: 300px;
		height: 100%;
		width: 100%;
		margin: 0 auto;
	}

	#flowDiv ::v-deep canvas {
		height: 100%;
	}

	#flowDiv ::v-deep div {
		height: 100%;
	}
</style>
